﻿using System;
using System.Collections.Generic;
using System.Threading;

namespace Plugins.Threading
{
    public abstract class PluginBaseWorkItem<T>
    {
        private static object _sync = new object();
        private T _item;
        public T Item { get { return _item; } }
        public void Run()
        {
            InitializeItem();
            List<WaitHandle> _waitHandles = new List<WaitHandle>();
            for (int i = 0; i < TaskCount; i++)
            {
                _waitHandles.Add(new AutoResetEvent(false));
            }
            for (int i = 0; i < TaskCount; i++)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessHandle), _waitHandles[i]);
            }
            WaitHandle.WaitAll(_waitHandles.ToArray());
            FinalizeItem();
        }
        protected virtual void InitializeItem() { }
        protected virtual void FinalizeItem() { }
        protected abstract void ProcessItem();
        protected void SetValue(T item)
        {
            _item = item;
        }
        protected T GetValue()
        {
            return _item;
        }
        protected virtual int TaskCount { get { return Environment.ProcessorCount; } }
        private void Process()
        {
            ProcessItem();
        }
        private void ProcessHandle(object sync)
        {
            AutoResetEvent waitHandle = (AutoResetEvent)sync;
            Process();
            waitHandle.Set();
        }
    }
}
